package com.hucheng.order.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.hucheng.common.constant.RedisConstant;
import com.hucheng.common.exception.EduException;
import com.hucheng.common.utils.AlipayUtils;
import com.hucheng.common.utils.CommonUtils;
import com.hucheng.common.utils.RedisUtils;
import com.hucheng.order.config.AliPaySystem;
import com.hucheng.order.entity.BalanceGoodsDO;
import com.hucheng.order.entity.GoodsDO;
import com.hucheng.order.entity.OrderInfoDO;
import com.hucheng.order.entity.OrderItemDO;
import com.hucheng.order.mapper.CartMapper;
import com.hucheng.order.mapper.GoodsMapper;
import com.hucheng.order.mapper.OrderInfoMapper;
import com.hucheng.order.mapper.OrderItemMapper;
import com.hucheng.order.service.OrderService;
import com.hucheng.order.vo.BalanceGoodsVo;
import com.hucheng.order.vo.BalanceOrderVO;
import com.hucheng.order.vo.OrderInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @Author: 凉白开不加冰
 * @Version: 0.0.1V
 * @Date: 2019-07-17
 * @Description: 订单实现类
 **/
@Slf4j
@Component
@Service(interfaceClass = OrderService.class, retries = -1, timeout = 5000)
public class OrderServiceImpl implements OrderService {

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private AliPaySystem aliPaySystem;

    private ExecutorService service = Executors.newFixedThreadPool(10);

    @Override
    public OrderInfoVO submitOrder(Integer userId) throws EduException {
        //从redis获取结算信息
        if (!RedisUtils.hasKey(stringRedisTemplate, RedisConstant.BALANCE_ORDER_KEY + userId)) {
            throw new EduException(170000);
        }
        BalanceOrderVO balanceOrderVO = RedisUtils.get(stringRedisTemplate, RedisConstant.BALANCE_ORDER_KEY + userId, BalanceOrderVO.class);
        //TODO：商品库存校验

        //TODO：扣除库存成功下单

        //创建订单
        OrderInfoDO orderInfoDO = new OrderInfoDO();
        orderInfoDO.setOrderNumber(CommonUtils.getOrderIdByTime());
        orderInfoDO.setUserId(userId);
        orderInfoDO.setStatus(0);
        orderInfoDO.setOrderAmount(balanceOrderVO.getPrice());
        orderInfoDO.setPayAmount(balanceOrderVO.getPayPrice());
        orderInfoDO.setTotalAmount(balanceOrderVO.getPrice());
        orderInfoDO.setAddressId(0);
        orderInfoDO.setRemark("");
        orderInfoDO.setIsDel(0);
        orderInfoMapper.insert(orderInfoDO);
        //创建子订单
        List<OrderItemDO> lists = new ArrayList<>();
        balanceOrderVO.getList().forEach(balanceGoodsVo -> {
            OrderItemDO orderItemDO = new OrderItemDO();
            orderItemDO.setOrderId(orderInfoDO.getOrderId());
            orderItemDO.setOrderItemNumber(CommonUtils.getOrderIdByTime());
            orderItemDO.setStatus(0);
            orderItemDO.setFormatId(0);
            orderItemDO.setUserId(userId);
            orderItemDO.setGoodsName(balanceGoodsVo.getGoodsName());
            orderItemDO.setGoodsNumber(balanceGoodsVo.getGoodsNumber());
            orderItemDO.setGoodsPrice(balanceGoodsVo.getGoodsPrice());
            orderItemDO.setGoodsAmount(balanceGoodsVo.getGoodsPrice());
            orderItemDO.setIsDel(0);
            lists.add(orderItemDO);
        });
        orderItemMapper.insert(lists);
        orderInfoDO.setOrderId(orderInfoDO.getOrderId());

        if (balanceOrderVO.getCartIds().size() > 0) {
            //清空购物车
            cartMapper.deleteBatch(balanceOrderVO.getCartIds(), userId);
        }

        //清除结算信息
        RedisUtils.del(stringRedisTemplate, RedisConstant.BALANCE_ORDER_KEY + userId);

        return OrderInfoVO.buildOrderInfoVO(orderInfoDO);
    }

    @Override
    public BalanceOrderVO getBalanceOrder(Integer userId, String cartIds, Integer goodsId, Integer goodsNumber) throws EduException {
        //获取用户购物车商品
        BalanceOrderVO balanceOrderVO = new BalanceOrderVO();
        balanceOrderVO.setUserId(userId);
        if (goodsId == 0) {
            //从购物车获取结算信息
            List<String> lists = Arrays.asList(cartIds.split(","));
            List<BalanceGoodsDO> goodsDOList = cartMapper.listByGoods(userId, lists);
            if (goodsDOList == null || goodsDOList.size() == 0) {
                throw new EduException(170000);
            }
            BigDecimal price = new BigDecimal(0);
            for (BalanceGoodsDO balanceGoodsDO : goodsDOList) {
                if (balanceGoodsDO.getGoodsPrice() != null) {
                    price = price.add(balanceGoodsDO.getGoodsPrice().multiply(new BigDecimal(balanceGoodsDO.getGoodsNumber())));
                }
            }
            balanceOrderVO.setPrice(price);
            balanceOrderVO.setPayPrice(price);
            balanceOrderVO.setDiscountAmount(new BigDecimal(0));
            balanceOrderVO.setIsFreeExpressPrice(0);
            balanceOrderVO.setList(goodsDOList.stream().map(BalanceGoodsVo::buildBalanceGoodsVo).collect(Collectors.toList()));
            balanceOrderVO.setCartIds(lists);
        } else {
            //根据商品id获取结算信息
            GoodsDO goodsDO = goodsMapper.get(goodsId);
            balanceOrderVO.setPrice(new BigDecimal(goodsDO.getGoodsPrice()).multiply(new BigDecimal(goodsNumber)));
            balanceOrderVO.setPayPrice(new BigDecimal(goodsDO.getGoodsPrice()).multiply(new BigDecimal(goodsNumber)));
            balanceOrderVO.setDiscountAmount(new BigDecimal(0));
            balanceOrderVO.setIsFreeExpressPrice(0);

            List<BalanceGoodsVo> lists = new ArrayList<>();
            BalanceGoodsDO balanceGoodsDO = new BalanceGoodsDO();
            balanceGoodsDO.setUserId(userId);
            balanceGoodsDO.setGoodsId(goodsDO.getGoodsId());
            balanceGoodsDO.setGoodsName(goodsDO.getGoodsName());
            balanceGoodsDO.setGoodsNumber(goodsNumber);
            balanceGoodsDO.setGoodsPrice(new BigDecimal(goodsDO.getGoodsPrice()));
            lists.add(BalanceGoodsVo.buildBalanceGoodsVo(balanceGoodsDO));

            balanceOrderVO.setList(lists);
            balanceOrderVO.setCartIds(new ArrayList<>());

        }
        //将结算信息放进redis缓存几分钟
        RedisUtils.set(stringRedisTemplate, RedisConstant.BALANCE_ORDER_KEY + userId, JSON.toJSONString(balanceOrderVO), 180);
        return balanceOrderVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderStatus(Map<String, String> params) throws EduException {
        String outTradeNo = params.get("out_trade_no");
        String tradeNo = params.get("trade_no");
        String totalAmount = params.get("total_amount");
        OrderInfoDO orderInfoDO = orderInfoMapper.getOrderInfoByOutTradeNo(params.get("out_trade_no"));
        if (orderInfoDO == null) {
            throw new EduException(170001);
        }
        //修改总订单状态
        orderInfoMapper.update(outTradeNo, tradeNo);
        //修改子订单状态
        orderItemMapper.update(orderInfoDO.getOrderId(), orderInfoDO.getUserId());
    }

    @Override
    public OrderInfoVO getOrderInfoByoutTradeNo(String outTradeNo) {
        return OrderInfoVO.buildOrderInfoVO(orderInfoMapper.getOrderInfoByOutTradeNo(outTradeNo));
    }

    @Override
    public String queryAliOrder(String outTradeNo) throws UnsupportedEncodingException, AlipayApiException {

        AlipayClient alipayClient = AlipayUtils.getAlipayClient(aliPaySystem.getAliPay());

        //查询订单信息
        OrderInfoVO orderInfoVO = OrderInfoVO.buildOrderInfoVO(orderInfoMapper.getOrderInfoByOutTradeNo(outTradeNo));

        AlipayTradeQueryRequest alipayTradeQueryRequest = new AlipayTradeQueryRequest();

        String out_trade_no = new String(outTradeNo.getBytes("ISO-8859-1"), "utf-8");

        JSONObject bizContent = new JSONObject();

        if (orderInfoVO.getTradeNo() != null) {
            String trade_no = new String(orderInfoVO.getTradeNo().getBytes("ISO-8859-1"), "utf-8");
            bizContent.put("out_trade_no", out_trade_no);
            bizContent.put("trade_no", trade_no);
            bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
            alipayTradeQueryRequest.setBizContent(bizContent.toJSONString());
        }

        bizContent.put("out_trade_no", out_trade_no);
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");

        alipayTradeQueryRequest.setBizContent(bizContent.toJSONString());

        String result = alipayClient.execute(alipayTradeQueryRequest).getBody();
        return result;
    }

    @Override
    public void updateOrderStatus() {
        service.execute(() -> {
            List<OrderInfoDO> lists = orderInfoMapper.listsByStatus();
            //查询数据库未支付的订单
            lists.forEach(orderInfoDO -> {
                log.info("修改支付订单状态开始 >>>>>>> " + JSONObject.toJSONString(lists));
                try {
                    AlipayClient alipayClient = AlipayUtils.getAlipayClient(aliPaySystem.getAliPay());
                    AlipayTradeQueryRequest alipayTradeQueryRequest = new AlipayTradeQueryRequest();
                    String outTradeNo = new String(orderInfoDO.getOrderNumber().getBytes("ISO-8859-1"), "utf-8");

                    JSONObject bizContent = new JSONObject();
                    bizContent.put("out_trade_no", outTradeNo);
                    bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");

                    alipayTradeQueryRequest.setBizContent(bizContent.toJSONString());

                    AlipayTradeQueryResponse response = alipayClient.execute(alipayTradeQueryRequest);
                    JSONObject jsonObject = JSONObject.parseObject(response.getBody());
                    JSONObject result = jsonObject.getJSONObject("alipay_trade_query_response");
                    log.info("支付宝返回订单状态 >>>>>>>> " + result);
                    if (result.getString("code").equals("10000")) {
                        if (result.getString("trade_status").equals("TRADE_SUCCESS")) {
                            //支付成功修改支付状态
                            orderInfoMapper.update(outTradeNo, result.getString("trade_no"));
                            //修改子订单状态
                            orderItemMapper.update(orderInfoDO.getOrderId(), orderInfoDO.getUserId());
                            log.info("修改支付订单状态结束 >>>>>>> " + JSONObject.toJSONString(orderInfoDO));
                        }
                    }
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                } catch (AlipayApiException e) {
                    e.printStackTrace();
                }
            });
        });
    }
}
